package com.hospital.hospitalsystem.modules.doctor.biz;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hospital.hospitalsystem.base.PageData;
import com.hospital.hospitalsystem.modules.doctor.dao.entity.BookRecordEntity;
import com.hospital.hospitalsystem.modules.doctor.dao.entity.DoctorIntroduceEntity;
import com.hospital.hospitalsystem.modules.doctor.dao.entity.PrescriptionEntity;
import com.hospital.hospitalsystem.modules.doctor.dto.*;
import com.hospital.hospitalsystem.modules.doctor.service.BookRecordService;
import com.hospital.hospitalsystem.modules.doctor.service.DoctorIntroduceService;
import com.hospital.hospitalsystem.modules.doctor.service.PrescriptionService;
import com.hospital.hospitalsystem.modules.hospital.dao.entity.DoctorOrderDetailEntity;
import com.hospital.hospitalsystem.modules.hospital.dao.entity.DoctorOrderEntity;
import com.hospital.hospitalsystem.modules.hospital.dto.DoctorGetReq;
import com.hospital.hospitalsystem.modules.hospital.dto.DoctorListRsp;
import com.hospital.hospitalsystem.modules.hospital.service.DoctorOrderService;
import com.hospital.hospitalsystem.modules.login.biz.LoginBiz;
import com.hospital.hospitalsystem.modules.medicine.dao.entity.HospitalMedicalEntity;
import com.hospital.hospitalsystem.modules.medicine.dto.PrescriptionOutExt;
import com.hospital.hospitalsystem.modules.medicine.service.HospitalMedicalService;
import com.hospital.hospitalsystem.modules.user.dao.entity.BookEntity;
import com.hospital.hospitalsystem.modules.user.service.BookService;
import com.hospital.hospitalsystem.utils.TimeUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.print.Doc;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author qiancheng@cqxyy.net
 * @date 2023/2/24
 */
@Service
public class DoctorBiz {

    @Autowired
    private LoginBiz loginBiz;

    @Autowired
    private BookService bookService;

    @Autowired
    private DoctorIntroduceService doctorIntroduceService;

    @Autowired
    private BookRecordService bookRecordService;

    @Autowired
    private DoctorOrderService doctorOrderService;

    @Autowired
    private HospitalMedicalService hospitalMedicalService;

    @Autowired
    private PrescriptionService prescriptionService;
    /**
     * 医生查看预约信息
     * @param req
     * @return
     */
    public PageData<DoctorBookRsp> bookList(DoctorBookReq req) {
        Date startWeek = null; Date endWeek = null;
        List<Integer> status = req.getStatus();
        if (req.getJudge() != null){
            //本周和下周
            if (req.getJudge() == 1 || req.getJudge() == 4) {
                Date now = new Date();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(now);
                Integer extDay = 0;
                if (req.getJudge() == 4) {
                    extDay = 7;
                }
                calendar.add(Calendar.DATE, TimeUtils.getMondayPlus(now) + 1 + extDay);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND,0);
                startWeek = calendar.getTime();

                calendar.add(Calendar.DATE, 6);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND,999);
                endWeek = calendar.getTime();
//                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                System.out.println("startTime:" + simpleDateFormat.format(startWeek));
//                System.out.println("endTime:" + simpleDateFormat.format(endWeek));
            }
            //当日
            if(req.getJudge() == 3) {
                Date now = new Date();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(now);
                calendar.set(Calendar.HOUR_OF_DAY,0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND,0);
                startWeek = calendar.getTime();

                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND,999);
                endWeek = calendar.getTime();
            }
        }
        Page<BookEntity> page = PageHelper.startPage(
                req.getCurrentPage(), req.getPageSize()
        );
        Map<DoctorBookExt,Date> list = bookService.selectDate(startWeek,endWeek,status,req.getHospitalUuid(),req.getDoctorUuid()).stream().collect(Collectors.toMap(
               s->s,DoctorBookExt::getDate
        ));
        Map<DoctorBookExt,List<DoctorBookTmpExt>> list1 = bookService.selectTmp(startWeek,endWeek,status,req.getHospitalUuid(),req.getDoctorUuid())
                .stream().collect(Collectors.groupingBy(s ->{
                    DoctorBookExt doctorBookExt = new DoctorBookExt();
                    doctorBookExt.setHospitalUuid(s.getHospitalUuid());
                    doctorBookExt.setDoctorUuid(s.getDoctorUuid());
                    doctorBookExt.setDate(s.getDate());
                    return doctorBookExt;
                }));
        List<DoctorBookRsp> result = new ArrayList<>();
        list.entrySet().stream().forEach(s->{
            DoctorBookRsp doctorBookRsp = new DoctorBookRsp();
            doctorBookRsp.setDay(s.getValue());
            List<DoctorBookRsp.TimePeriod> timePeriodList = new ArrayList<>();
            List<DoctorBookTmpExt> tmp = list1.get(s.getKey());
            for (DoctorBookTmpExt doctorBookTmpExt : tmp){
                doctorBookTmpExt.setUserAge(loginBiz.getAgeFromIdCard(doctorBookTmpExt.getIdCard()));
                DoctorBookRsp.TimePeriod timePeriod = new DoctorBookRsp.TimePeriod();
                BeanUtils.copyProperties(doctorBookTmpExt,timePeriod);
                timePeriodList.add(timePeriod);
            }
            if (CollectionUtils.isNotEmpty(timePeriodList)){
                doctorBookRsp.setTimePeriodList(timePeriodList);
                result.add(doctorBookRsp);
            }
        });
        int longs = ((Number) page.getTotal()).intValue();
        PageData<DoctorBookRsp> pageData = PageData.of(result,page.getPageNum(),page.getPageSize(),longs);
        return pageData;
    }

    /**
     * 医生完成预约
     * @param req
     */
    public void bookFinish(DoctorFinishReq req) {
        Example exampleBook = new Example(BookEntity.class);
        Example.Criteria criteriaBook = exampleBook.createCriteria();
        criteriaBook.andEqualTo("uuid",req.getOrderUuid());
        criteriaBook.andEqualTo("hospitalUuid",req.getHospitalUuid());
        criteriaBook.andEqualTo("doctorUuid",req.getDoctorUuid());
        BookEntity bookEntity = new BookEntity();
        bookEntity.setStatus(5);
        bookService.updateByExampleSelective(bookEntity,exampleBook);
        Example examplePrescription = new Example(PrescriptionEntity.class);
        Example.Criteria criteriaPrescription = examplePrescription.createCriteria();
        criteriaPrescription.andEqualTo("bookUuid",req.getOrderUuid());
        PrescriptionEntity prescriptionEntity = new PrescriptionEntity();
        prescriptionEntity.setStatus(2);
        prescriptionService.updateByExampleSelective(prescriptionEntity,examplePrescription);
//        Map<String,Integer> medicals = req.getList().stream().collect(Collectors.toMap(s->s.getMedicalUuid(),s->s.getCount()));
//        List<String> medicalUuids = req.getList().stream().map(s->s.getMedicalUuid()).collect(Collectors.toList());
//        Example exampleHospitalMedical = new Example(HospitalMedicalEntity.class);
//        Example.Criteria criteriaHospitalMedical = exampleHospitalMedical.createCriteria();
//        criteriaHospitalMedical.andIn("medicalUuid",medicalUuids);
//        criteriaBook.andEqualTo("hospitalUuid",req.getHospitalUuid());
//        List<HospitalMedicalEntity> list = hospitalMedicalService.selectByExample(exampleHospitalMedical);
//        list.forEach(s -> {
//            HospitalMedicalEntity hospitalMedicalEntity = new HospitalMedicalEntity();
//            hospitalMedicalEntity.setReserveCount(s.getReserveCount() - medicals.get(s.getMedicalUuid()));
//            Example example = new Example(HospitalMedicalEntity.class);
//            Example.Criteria criteria = example.createCriteria();
//            criteria.andEqualTo("hospitalUuid",req.getHospitalUuid());
//            criteria.andEqualTo("medicalUuid", s.getMedicalUuid());
//            hospitalMedicalService.updateByExampleSelective(hospitalMedicalEntity,example);
//        });
    }

    /**
     * 医生填写个人信息
     * @param req
     */
    public void introduce(DoctorIntroduceReq req) {
        Example exampleIntroduce = new Example(DoctorIntroduceEntity.class);
        Example.Criteria criteriaIntroduce = exampleIntroduce.createCriteria();
        criteriaIntroduce.andEqualTo("hospitalUuid",req.getHospitalUuid());
        criteriaIntroduce.andEqualTo("doctorUuid",req.getDoctorUuid());
        DoctorIntroduceEntity doctorIntroduceEntity = doctorIntroduceService.selectByExample(exampleIntroduce).get(0);
        doctorIntroduceEntity.setBasic(req.getBasic());
        doctorIntroduceEntity.setExperience(req.getExperience());
        doctorIntroduceEntity.setSpecialty(req.getSpecialty());
        if (req.getStatus() == null) {
            doctorIntroduceEntity.setStatus(2);
        }else{
            doctorIntroduceEntity.setStatus(req.getStatus());
        }
        doctorIntroduceService.updateByPrimaryKeySelective(doctorIntroduceEntity);
    }

    /**
     * 医生查看个人信息
     * @param req
     * @return
     */
    public DoctorIntroduceRsp introduceShow(DoctorIntroduceReq req) {
        Example exampleIntroduce = new Example(DoctorIntroduceEntity.class);
        Example.Criteria criteriaIntroduce = exampleIntroduce.createCriteria();
        criteriaIntroduce.andEqualTo("hospitalUuid",req.getHospitalUuid());
        criteriaIntroduce.andEqualTo("doctorUuid",req.getDoctorUuid());
        List<DoctorIntroduceEntity> list = doctorIntroduceService.selectByExample(exampleIntroduce);
        if (CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("此医生不存在个人信息");
        } else {
            DoctorIntroduceRsp doctorIntroduceRsp = new DoctorIntroduceRsp();
            BeanUtils.copyProperties(list.get(0),doctorIntroduceRsp);
            return doctorIntroduceRsp;
        }
    }

    /**
     * 医生修改个人信息
     * @param req
     */
    public void introduceUpdate(DoctorIntroduceReq req) {
        Example exampleIntroduce = new Example(DoctorIntroduceEntity.class);
        Example.Criteria criteriaIntroduce = exampleIntroduce.createCriteria();
        criteriaIntroduce.andEqualTo("hospitalUuid",req.getHospitalUuid());
        criteriaIntroduce.andEqualTo("doctorUuid",req.getDoctorUuid());
        DoctorIntroduceEntity doctorIntroduceEntity = new DoctorIntroduceEntity();
        doctorIntroduceEntity.setBasic(req.getBasic());
        doctorIntroduceEntity.setExperience(req.getExperience());
        doctorIntroduceEntity.setSpecialty(req.getSpecialty());
        doctorIntroduceEntity.setStatus(2);
        doctorIntroduceEntity.setReason("");
        doctorIntroduceService.updateByExampleSelective(doctorIntroduceEntity,exampleIntroduce);
    }

    /**
     * 医生叫号检查
     * @param req
     * @return
     */
    public DoctorNumberCheckRsp numberCheck(DoctorNumberCheckReq req) {
        SimpleDateFormat dfDate = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = new Date();
        req.setNowDate(dfDate.format(nowDate));
        List<DoctorNumberCheckExt> list = bookService.numberCheck(req);
        DoctorNumberCheckRsp doctorNumberCheckRsp = new DoctorNumberCheckRsp();
        int status = 1;
        String errorMessage = null;
        if (CollectionUtils.isEmpty(list)) {
            status = 4;
            errorMessage = DoctorNumberCheckFinal.NULL;
        }else {
            DoctorNumberCheckExt item = list.get(0);
            LocalTime startTime = item.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
            LocalTime endTime = item.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
            LocalTime nowDateLocal = nowDate.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
            if (nowDateLocal.compareTo(endTime) > 0) {
                status = 2;
                errorMessage = DoctorNumberCheckFinal.FRONT;
            }
            if (nowDateLocal.compareTo(startTime) < 0) {
                status = 3;
                errorMessage = DoctorNumberCheckFinal.BACK;
            }
        }
        doctorNumberCheckRsp.setCheckStatus(status);
        doctorNumberCheckRsp.setCheckMessage(errorMessage);
        return doctorNumberCheckRsp;
    }

    /**
     * 医生叫号
     * @param req
     * @return
     */
    public DoctorNumberRsp number(DoctorNumberCheckReq req) {
        SimpleDateFormat dfDate = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = new Date();
        req.setNowDate(dfDate.format(nowDate));
        List<DoctorNumberCheckExt> list = bookService.numberCheck(req);
        DoctorNumberRsp doctorNumberRsp = new DoctorNumberRsp();
        if (CollectionUtils.isNotEmpty(list)) {
            doctorNumberRsp.setBookUuid(list.get(0).getBookUuid());
            Example exampleBook = new Example(BookEntity.class);
            Example.Criteria criteriaBook = exampleBook.createCriteria();
            criteriaBook.andEqualTo("uuid",list.get(0).getBookUuid());
            criteriaBook.andEqualTo("hospitalUuid",req.getHospitalUuid());
            criteriaBook.andEqualTo("doctorUuid",req.getDoctorUuid());
            BookEntity bookEntity = new BookEntity();
            bookEntity.setStatus(3);
            bookService.updateByExampleSelective(bookEntity,exampleBook);
        }
        return doctorNumberRsp;
    }

    /**
     * 根据uuid获取用户信息
     * @param req
     * @return
     */
    public MessageBookUuidRsp messageBookUuid(MessageBookUuidReq req) {
        MessageBookUuidRsp messageBookUuidRsp = new MessageBookUuidRsp();
        List<MessageBookUuidRsp> list = bookService.messageBookUuid(req);
        if (CollectionUtils.isNotEmpty(list)) {
            messageBookUuidRsp = list.get(0);
        }
        return messageBookUuidRsp;
    }

    /**
     * 根据订单uuid获取诊疗记录
     * @param req
     * @return
     */
    public BookRecordRsp recordBookUuid(MessageBookUuidReq req) {
        Example exampleRecord = new Example(BookRecordEntity.class);
        Example.Criteria criteriaRecord = exampleRecord.createCriteria();
        if (StringUtils.isNotBlank(req.getBookUuid())) {
            criteriaRecord.andEqualTo("bookUuid",req.getBookUuid());
        }
        List<BookRecordRsp> list = bookRecordService.selectByExample(exampleRecord).stream().map(s -> {
            BookRecordRsp bookRecordRsp = new BookRecordRsp();
            BeanUtils.copyProperties(s,bookRecordRsp);
            return bookRecordRsp;
        }).collect(Collectors.toList());
        BookRecordRsp bookRecordRsp = new BookRecordRsp();
        if (CollectionUtils.isNotEmpty(list)) {
            bookRecordRsp = list.get(0);
        }
        return bookRecordRsp;
    }

    /**
     * 根据bookUuid获取药方详情
     * @param req
     * @return
     */
    public PrescriptionRsp prescriptionBookUuid(MessageBookUuidReq req) {
        Example examplePrescription = new Example(PrescriptionEntity.class);
        Example.Criteria criteriaPrescription = examplePrescription.createCriteria();
        criteriaPrescription.andEqualTo("bookUuid",req.getBookUuid());
        List<PrescriptionEntity> list = prescriptionService.selectByExample(examplePrescription);
        PrescriptionRsp prescriptionRsp = new PrescriptionRsp();
        if (CollectionUtils.isNotEmpty(list)) {
            BeanUtils.copyProperties(list.get(0),prescriptionRsp);
        }
        return prescriptionRsp;
    }

    /**
     * 根据bookUuid修改诊疗记录
     * @param req
     */
    public void recordBookUuidUpdate(BookRecordReq req) {
        BookRecordEntity bookRecordEntity = new BookRecordEntity();
        Example exampleBookRecord = new Example(BookRecordEntity.class);
        Example.Criteria criteriaPrescription = exampleBookRecord.createCriteria();
        criteriaPrescription.andEqualTo("bookUuid",req.getBookUuid());
        bookRecordEntity.setDoctorDescription(req.getDoctorDescription());
        bookRecordEntity.setDoctorStatus(req.getDoctorStatus());
        bookRecordEntity.setUserDescription(req.getUserDescription());
        bookRecordEntity.setUserStatus(req.getUserStatus());
        bookRecordService.updateByExampleSelective(bookRecordEntity,exampleBookRecord);
    }

    /**
     * 根据bookUuid增加诊疗记录
     * @param req
     */
    public void recordBookUuidAdd(BookRecordReq req) {
        BookRecordEntity bookRecordEntity = new BookRecordEntity();
        bookRecordEntity.setRecordUuid(UUID.randomUUID().toString());
        bookRecordEntity.setBookUuid(req.getBookUuid());
        bookRecordEntity.setDoctorStatus(req.getDoctorStatus());
        bookRecordEntity.setDoctorDescription(req.getDoctorDescription());
        bookRecordEntity.setUserStatus(req.getUserStatus());
        bookRecordEntity.setUserDescription(req.getUserDescription());
        bookRecordService.insertSelective(bookRecordEntity);
    }

    /**
     * 根据bookUuid修改药方详情
     * @param req
     */
    public void prescriptionBookUuidUpdate(PrescriptionReq req) {
        Example examplePrescription = new Example(PrescriptionEntity.class);
        Example.Criteria criteriaPrescription = examplePrescription.createCriteria();
        criteriaPrescription.andEqualTo("bookUuid",req.getBookUuid());
        PrescriptionEntity prescriptionEntity = new PrescriptionEntity();
        prescriptionEntity.setPrescription(req.getPrescription());
        prescriptionService.updateByExampleSelective(prescriptionEntity,examplePrescription);
    }

    /**
     * 根据bookUuid删除诊疗记录
     * @param req
     */
    public void recordBookUuidDelete(BookRecordReq req) {
        Example exampleBookRecord = new Example(BookRecordEntity.class);
        Example.Criteria criteriaPrescription = exampleBookRecord.createCriteria();
        criteriaPrescription.andEqualTo("bookUuid",req.getBookUuid());
        bookRecordService.deleteByExample(exampleBookRecord);
    }

    /**
     * 根据bookUuid增加药方详情
     * @param req
     */
    public void prescriptionBookUuidAdd(PrescriptionReq req) {
        PrescriptionEntity prescriptionEntity = new PrescriptionEntity();
        prescriptionEntity.setPrescriptionUuid(UUID.randomUUID().toString());
        prescriptionEntity.setBookUuid(req.getBookUuid());
        prescriptionEntity.setPrescription(req.getPrescriptionUuid());
        prescriptionEntity.setStatus(1);
        prescriptionService.insertSelective(prescriptionEntity);
    }

    /**
     * 根据bookUuid删除药方详情
     * @param req
     */
    public void prescriptionBookUuidDelete(PrescriptionReq req) {
        Example examplePrescription = new Example(PrescriptionEntity.class);
        Example.Criteria criteriaPrescription = examplePrescription.createCriteria();
        criteriaPrescription.andEqualTo("bookUuid",req.getBookUuid());
        prescriptionService.deleteByExample(examplePrescription);
    }

    public DoctorNumberRsp start(DoctorStartReq req) {
        Example exampleBook = new Example(BookEntity.class);
        Example.Criteria criteriaBook = exampleBook.createCriteria();
        criteriaBook.andEqualTo("uuid",req.getBookUuid());
        criteriaBook.andEqualTo("hospitalUuid",req.getHospitalUuid());
        criteriaBook.andEqualTo("doctorUuid",req.getDoctorUuid());
        BookEntity bookEntity = new BookEntity();
        bookEntity.setStatus(4);
        bookService.updateByExampleSelective(bookEntity,exampleBook);
        DoctorNumberRsp doctorNumberRsp = new DoctorNumberRsp();
        doctorNumberRsp.setBookUuid(req.getBookUuid());
        return doctorNumberRsp;
    }

    /**
     * 问诊师获取预约时刻表
     * @param req
     * @return
     */
    public List<GetBookTimeRsp> getBookTime(DoctorGetReq req) {
        Map<Integer,List<DoctorOrderEntity>> tmp = doctorOrderService.getBookTime(req).stream().
                collect(Collectors.groupingBy(s->s.getDay()));
        List<GetBookTimeRsp> result = new ArrayList<>();
        tmp.forEach((key,value) -> {
            GetBookTimeRsp getBookTimeRsp = new GetBookTimeRsp();
            getBookTimeRsp.setList(value.stream().map(s-> {
                GetBookTimeExt getBookTimeExt = new GetBookTimeExt();
                BeanUtils.copyProperties(s,getBookTimeExt);
                return getBookTimeExt;
            }).collect(Collectors.toList()));
            getBookTimeRsp.setDay(key);
            result.add(getBookTimeRsp);
        });
        return result;
    }
}
